#include "threadpool.h"


void* worker(void * argu)
{

    threadpool* pool = (threadpool*)argu;
    cout<<"threadpool: woker thread create\n";

    while(!pool->shutdown)
    {
        
        sqltask sqltaskins;

        pthread_mutex_lock(&pool->mutexthreadpool);
        cout<<"threadpool: worker blocken\n";
        pthread_cond_wait(&pool->sigNotempty,&pool->mutexthreadpool);
        if(pool->shutdown)
        {
            pthread_mutex_unlock(&pool->mutexthreadpool);
            break;
        }
        cout<<"threadpool: worker awaken\n";
        if((pool->taskqueue.size())>0)
        {
            sqltaskins=pool->taskqueue.front();
            pool->taskqueue.pop();
        }
        pthread_mutex_unlock(&pool->mutexthreadpool);

        pthread_mutex_lock(&pool->mutexbusyerNum);
        pool->busyerNum++;
        pthread_mutex_unlock(&pool->mutexbusyerNum);
        
        if(sqltaskins.func!=NULL)
        {
            sqltaskins.func(sqltaskins.argu);
        }else
        {
            cout<<"threadpool: worker func = NULL\n";
        }

        pthread_mutex_lock(&pool->mutexbusyerNum);
        pool->busyerNum--;
        pthread_mutex_unlock(&pool->mutexbusyerNum);

    }
}
    
void threadpool::init()
{

    pthread_mutex_init(&mutextaskqueue,NULL);
    pthread_mutex_init(&mutexthreadpool,NULL);
    pthread_mutex_init(&mutexbusyerNum,NULL);

    pthread_cond_init(&sigNotfull,NULL);
    pthread_cond_init(&sigNotempty,NULL);

    workerNum=4;
    busyerNum=0;
    shutdown=false;

    tids=(pthread_t*)malloc(sizeof(pthread_t)*16);

  
    for(int i=0;i<4;i++)
    {
        pthread_create(&tids[i],NULL,worker,this);
    }
}



void threadpool::addtask(sqltask sqltask )//callback func, argument argu)
{
    
    pthread_mutex_lock(&mutexthreadpool);
    taskqueue.push(sqltask);
    pthread_mutex_unlock(&mutexthreadpool);
    pthread_cond_signal(&sigNotempty);
    cout<<"threadpool: add task ---> push task and set sig\n";
}




void threadpool::deinit()
{
    for(int i=0;i<4;i++)
    {
        pthread_join(tids[i],nullptr);
    }
}